package Introspector;


import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class Common
{

    public Common()
    {
    }

    public static Map<Class<?>,ClassInfo> getAllClassInfo()
    {
        return classInfoCache;
    }

    private static ClassInfo getClassInfo(Class<?> clazz)
    {
        ClassInfo ci = (ClassInfo)classInfoCache.get(clazz);
        if(ci == null){
			try{
                ci = new ClassInfo(clazz);
                classInfoCache.putIfAbsent(clazz, ci);
			} catch (Exception e) {
				e.printStackTrace();
			}
        }
        return ci;
    }

    public static Field getFieldByName(Class<?> clazz, String fieldName) throws Exception
	{
	    ClassInfo ci = getClassInfo(clazz);
	    Map<String,Field> mapAllField = ci.getMapAllDBField();
	    return mapAllField.get(fieldName);
	}

    public static Method getSetterMethod(Class<?> clazz, String fieldName)
        throws Exception
    {
        ClassInfo ci = getClassInfo(clazz);
        Map<String,Method> mapSetterMethod = ci.getMapSetMethod();
        return (Method)mapSetterMethod.get(fieldName);
    }

    public static Method getGetterMethod(Class<?> clazz, String fieldName)
    {
        ClassInfo ci = getClassInfo(clazz);
        Map<String,Method> mapGetterMethod = ci.getMapGetMethod();
        return (Method)mapGetterMethod.get(fieldName);
    }


    public static List<Field> getAllFields(Class<?> clazz)
    {
        ClassInfo ci = getClassInfo(clazz);
        Collection<Field> coll = ci.getMapAllDBField().values();
        List<Field> fields = new ArrayList<Field>();
        Field f;
        for(Iterator<Field> iterator = coll.iterator(); iterator.hasNext(); fields.add(f))
            f = (Field)iterator.next();

        return fields;
    }

    public static String getTableName(Class<?> clazz)
    {
        return getClassInfo(clazz).getTableName();
    }

    public static String getDBCloumnName(Class<?> clazz, String fieldName)
    {
        ClassInfo ci = getClassInfo(clazz);
        return (String)ci.getMapDBColumnName().get(fieldName);
    }

    public static String getTableRename(Class<?> clazz, Object bean)
    {
        String value = null;
        ClassInfo ci = getClassInfo(clazz);
        Collection<Field> coll = ci.getMapTableRenameField().values();
        for(Iterator<Field> iterator = coll.iterator(); iterator.hasNext();)
        {
            Field f = (Field)iterator.next();
            Method m = getTableRenameGetterMethod(clazz, f.getName());
            try
            {
                value = String.valueOf(m.invoke(bean, new Object[0]));
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }

        return value;
    }

    public static Method getTableRenameGetterMethod(Class<?> clazz, String fieldName)
    {
        ClassInfo ci = getClassInfo(clazz);
        Map<String,Method> mapGetterMethod = ci.getMapTableRenameGetMethod();
        return (Method)mapGetterMethod.get(fieldName);
    }

    public static String getValue(Object bean, Method method)
        throws Exception
    {
        String retValue = "";
        Object valueObj = method.invoke(bean, new Object[0]);
        Class<?> valueType = method.getReturnType();
        if(valueType.equals(java.lang.String.class))
        {
            if(valueObj == null)
                retValue = "''";
            else
                retValue = (new StringBuilder("'")).append(valueObj.toString()).append("'").toString();
        } else
        if(valueType.equals(java.sql.Timestamp.class) || valueType.equals(java.sql.Date.class) || valueType.equals(java.util.Date.class))
        {
            if(valueObj == null)
                retValue = "''";
            else
                retValue = (new StringBuilder("'")).append(sdf.format(valueObj)).append("'").toString();
        } else
        if(valueType.equals(Boolean.TYPE) || valueType.equals(java.lang.Boolean.class))
        {
            if(valueObj != null && valueObj.toString().equalsIgnoreCase("true"))
                retValue = "1";
            else
                retValue = "0";
        } else
        if(valueObj == null)
            retValue = "null";
        else
            retValue = valueObj.toString();
        return retValue;
    }

    public static String getValue(Object value)
        throws Exception
    {
        String retValue = "";
        Class<?> clazz = value.getClass();
        if(clazz == java.lang.String.class || clazz == java.util.Date.class || clazz == java.sql.Date.class)
            retValue = (new StringBuilder("'")).append(value.toString()).append("'").toString();
        else
            retValue = value.toString();
        return retValue;
    }

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    private static  ConcurrentHashMap<Class<?>,ClassInfo> classInfoCache = new ConcurrentHashMap<Class<?>,ClassInfo>();

}
